package com.wanger.swc.util.mybatisplus;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.util.*;

/**
 * @Author: wanger
 * @Date: 2024/12/24 15:35
 * @Description: 该工具为单表查询条件构造类，可类似MyBatis-plus的链式调用构造条件，并且不需要多余的判空操作<br/>
 * 使用示例：
 * <ol>
 *         <li>使用示例【<pre>{@code
 *         List<UserEntity> list = userService.list(
 *              MyWrapper.create(UserEntity.class)
 *                 .eq(UserEntity::getStatus, DataStatus.NORMAL.getStatus())
 *                 .like(query::getName)
 *                 //其他条件
 *                 .order(Order.DESC(UserEntity::getCreatedTime)));
 *         }</pre>】</li>
 * </ol><br/>
 * 扩展需遵循规范：<br/>
 * 1.当前方法功能为【数据库字段 操作符 操作值】模式时需提供两个方法，<br/>
 * 1.1.方法名将标识操作符，<br/>
 * 1.2.方法一为一个入参，参数为lambda函数参数入参，<br/>
 * 1.3.方法二为两个入参，参数1为lambda函数入参，参数2为操作值入参，<br/>
 * 2.当方法功能为【数据库字段 操作符】模式时只需提供一个方法
 * 2.1.方法名将标识操作符<br/>
 * 2.2.方法为一个入参，参数为lambda函数参数入参，<br/>
 * 3.方法结束需return this以保证链式调用不被中断<br/>
 * 4.方法必须添加必要的字段与返回值注释，并且需要说明方法的【功能，使用示例，效果】<br/>
 * 5.<span style="color:red">禁止</span>在方法内写定制化代码，如：【<br/>
 * <pre>{@code
 *  //定制代码
 *  if ("userId".equals(field)) {
 *      //定制逻辑
 *  }
 * }</pre>
 * 】<br/>
 */
public class MyWrapper<T> extends QueryWrapper<T> {
    private static final long serialVersionUID = 995137812341871522L;
    private final boolean filterNull;

    /**
     * 创建MyWrapper的构造方法
     */
    public MyWrapper(boolean filterNull) {
        this.filterNull = filterNull;
    }

    /**
     * 创建MyWrapper的构造方法
     */
    public MyWrapper() {
        this(true);
    }

    /**
     * 创建MyWrapper的静态方法
     *
     * @param <T> 实体类类型
     * @return MyWrapper实例
     */
    public static <T> MyWrapper<T> create(boolean filterNull) {
        return new MyWrapper<>(filterNull);
    }

    /**
     * 创建MyWrapper的静态方法
     *
     * @param <T> 实体类类型
     * @return MyWrapper实例
     */
    public static <T> MyWrapper<T> create() {
        return new MyWrapper<>();
    }

    /**
     * 创建MyWrapper的静态方法
     *
     * @param ignore 实体类类型
     * @param <T>    实体类类型
     * @return MyWrapper实例
     */
    public static <T> MyWrapper<T> create(Class<T> ignore) {
        return new MyWrapper<>();
    }

    /**
     * 创建MyWrapper的静态方法
     *
     * @param ignore 实体类类型
     * @param <T>    实体类类型
     * @return MyWrapper实例
     */
    public static <T> MyWrapper<T> create(Class<T> ignore, boolean filterNull) {
        return new MyWrapper<>(filterNull);
    }

    /**
     * 根据方法获取字段名称
     *
     * @param getFunc 获取字段的方法
     * @param <T>     获取字段的实体类型
     * @return 数据库字段名称
     */
    private static <T> String getColumn(Func0<T> getFunc) {
        return StrUtil.toUnderlineCase(LambdaUtil.getFieldName(getFunc));
    }

    /**
     * 根据方法获取字段名称
     *
     * @param getFunc 获取字段的方法
     * @param <T>     获取字段的实体类型
     * @return 数据库字段名称
     */
    private static <T> String getColumn(Func1<T, ?> getFunc) {
        return StrUtil.toUnderlineCase(LambdaUtil.getFieldName(getFunc));
    }

    private boolean comeIntoForceFun(Func0<?> getFunc) {
        if (getFunc == null) return false;
        Object value = getFunc.callWithRuntimeException();
        if (filterNull) {
            if (value instanceof String) {
                return StrUtil.isNotBlank((String) value);
            }
        }
        return value != null;
    }

    private boolean comeIntoForce(Object value) {
        if (filterNull) {
            if (value instanceof String) {
                return StrUtil.isNotBlank((String) value);
            } else if (value instanceof Func0<?>) {
                return comeIntoForceFun((Func0<?>) value);
            } else if (value instanceof Func1<?, ?>) {
                return true;
            } else if (value instanceof Map<?, ?>) {
                return CollUtil.isNotEmpty((Map<?, ?>) value);
            } else if (value instanceof Collection<?>) {
                return CollUtil.isNotEmpty((Collection<?>) value);
            } else if (value instanceof Iterable<?>) {
                return CollUtil.isNotEmpty((Iterable<?>) value);
            } else if (value instanceof Enumeration<?>) {
                return CollUtil.isNotEmpty((Enumeration<?>) value);
            }
        }
        return value != null;
    }

    /**
     * 查询字段指定【select 字段1, 字段2】<br/>
     * 使用示例【.like(UserEntity::getName, UserEntity::getAge)】<br/>
     * 效果【select name, age】<br/>
     *
     * @param getFuncs 字段与值的lambda函数
     * @return this
     */
    @SafeVarargs
    public final MyWrapper<T> select(Func1<T, ?>... getFuncs) {
        if (getFuncs != null) {
            this.select(Arrays.stream(getFuncs)
                    .filter(Objects::nonNull)
                    .map(MyWrapper::getColumn)
                    .toArray(String[]::new));
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 like ''】<br/>
     * 使用示例【.like(query::getName)】<br/>
     * 效果【name like '%张三%'】<br/>
     *
     * @param getFunc 字段与值的lambda函数
     * @return this
     */
    public MyWrapper<T> like(Func0<String> getFunc) {
        String value = getFunc.callWithRuntimeException();
        if (comeIntoForce(getFunc)) {
            this.like(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 like ''】<br/>
     * 使用示例【.like(UserEntity::getName, "张三")】<br/>
     * 效果【name like '%张三%'】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值
     * @return this
     */
    public MyWrapper<T> like(Func1<T, String> getFunc, String value) {
        if (comeIntoForce(value)) {
            this.like(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 like ''】<br/>
     * 使用示例【.likeLeft(query::getName)】<br/>
     * 效果【name like '%张三'】<br/>
     *
     * @param getFunc 字段与值的lambda函数
     * @return this
     */
    public MyWrapper<T> likeLeft(Func0<String> getFunc) {
        String value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.likeLeft(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 like ''】<br/>
     * 使用示例【.likeLeft(UserEntity::getName, "张三")】<br/>
     * 效果【name like '%张三'】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值
     * @return this
     */
    public MyWrapper<T> likeLeft(Func1<T, String> getFunc, String value) {
        if (comeIntoForce(value)) {
            this.likeLeft(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 like ''】<br/>
     * 使用示例【.likeRight(query::getName)】<br/>
     * 效果【name like '张三%'】<br/>
     *
     * @param getFunc 字段与值的lambda函数
     * @return this
     */
    public MyWrapper<T> likeRight(Func0<String> getFunc) {
        String value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.likeRight(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 like ''】<br/>
     * 使用示例【.likeRight(UserEntity::getName, "张三")】<br/>
     * 效果【name like '张三%'】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值
     * @return this
     */
    public MyWrapper<T> likeRight(Func1<T, String> getFunc, String value) {
        if (comeIntoForce(value)) {
            this.likeRight(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 not like ''】<br/>
     * 使用示例【.notLike(query::getName)】<br/>
     * 效果【name not like '%张三%'】<br/>
     *
     * @param getFunc 字段与值的lambda函数
     * @return this
     */
    public MyWrapper<T> notLike(Func0<String> getFunc) {
        String value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.notLike(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 not like ''】<br/>
     * 使用示例【.notLike(UserEntity::getName, "张三")】<br/>
     * 效果【name not like '%张三%'】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值
     * @return this
     */
    public MyWrapper<T> notLike(Func1<T, String> getFunc, String value) {
        if (comeIntoForce(value)) {
            this.notLike(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 not like ''】<br/>
     * 使用示例【.notLikeLeft(query::getName)】<br/>
     * 效果【name not like '%张三'】<br/>
     *
     * @param getFunc 字段与值的lambda函数
     * @return this
     */
    public MyWrapper<T> notLikeLeft(Func0<String> getFunc) {
        String value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.notLikeLeft(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 not like ''】<br/>
     * 使用示例【.notLikeLeft(UserEntity::getName, "张三")】<br/>
     * 效果【name not like '%张三'】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值
     * @return this
     */
    public MyWrapper<T> notLikeLeft(Func1<T, String> getFunc, String value) {
        if (comeIntoForce(value)) {
            this.notLikeLeft(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 not like ''】<br/>
     * 使用示例【.notLikeRight(query::getName)】<br/>
     * 效果【name not like '张三%'】<br/>
     *
     * @param getFunc 字段与值的lambda函数
     * @return this
     */
    public MyWrapper<T> notLikeRight(Func0<String> getFunc) {
        String value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.notLikeRight(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 模糊匹配判定【字段 not like ''】<br/>
     * 使用示例【.notLikeRight(UserEntity::getName, "张三")】<br/>
     * 效果【name not like '张三%'】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值
     * @return this
     */
    public MyWrapper<T> notLikeRight(Func1<T, String> getFunc, String value) {
        if (comeIntoForce(value)) {
            this.notLikeRight(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 为空判定【字段 is null】<br/>
     * 使用示例【.isNull(query::getName)】<br/>
     * 效果【name is null】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @return this
     */
    public MyWrapper<T> isNull(Func1<T, ?> getFunc) {
        if (comeIntoForce(getFunc)) {
            this.isNull(getColumn(getFunc));
        }
        return this;
    }

    /**
     * 为空判定【字段 is not null】<br/>
     * 使用示例【.isNotNull(query::getName)】<br/>
     * 效果【name is not null】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @return this
     */
    public MyWrapper<T> isNotNull(Func1<T, ?> getFunc) {
        if (comeIntoForce(getFunc)) {
            this.isNotNull(getColumn(getFunc));
        }
        return this;
    }

    /**
     * 小于等于判定【字段 <= 值】<br/>
     * 使用示例【.le(query::getAge)】<br/>
     * 效果【age <= 20】<br/>
     *
     * @param getFunc 字段与值的lambda函数，函数的返回值必须实现Comparable是可比较的
     * @param <V>     操作值的类型
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> le(Func0<V> getFunc) {
        V value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.le(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 <= 值】<br/>
     * 使用示例【.le(UserEntity::getAge, 20)】<br/>
     * 效果【age <= 20】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值,必须实现Comparable是可比较的
     * @param <V>     操作值的类型
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> le(Func1<T, V> getFunc, V value) {
        if (comeIntoForce(value)) {
            this.le(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 < 值】<br/>
     * 使用示例【.lt(query::getAge)】<br/>
     * 效果【age < 20】<br/>
     *
     * @param getFunc 字段与值的lambda函数，函数的返回值必须实现Comparable是可比较的
     * @param <V>     操作值的类型
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> lt(Func0<V> getFunc) {
        V value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.lt(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 < 值】<br/>
     * 使用示例【.lt(UserEntity::getAge, 20)】<br/>
     * 效果【age < 20】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值,必须实现Comparable是可比较的
     * @param <V>     操作值的类型
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> lt(Func1<T, V> getFunc, V value) {
        if (comeIntoForce(value)) {
            this.lt(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 >= 值】<br/>
     * 使用示例【.ge(query::getAge)】<br/>
     * 效果【age >= 20】<br/>
     *
     * @param getFunc 字段与值的lambda函数，函数的返回值必须实现Comparable是可比较的
     * @param <V>     操作值的类型
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> ge(Func0<V> getFunc) {
        V value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.ge(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 >= 值】<br/>
     * 使用示例【.ge(UserEntity::getAge, 20)】<br/>
     * 效果【age >= 20】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值,必须实现Comparable是可比较的
     * @param <V>     操作值的类型
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> ge(Func1<T, V> getFunc, V value) {
        if (comeIntoForce(value)) {
            this.ge(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 > 值】<br/>
     * 使用示例【.gt(query::getAge)】<br/>
     * 效果【age > 20】<br/>
     *
     * @param getFunc 字段与值的lambda函数，函数的返回值必须实现Comparable是可比较的
     * @param <V>     操作值的类型
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> gt(Func0<V> getFunc) {
        V value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.gt(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 > 值】<br/>
     * 使用示例【.gt(UserEntity::getAge, 20)】<br/>
     * 效果【age > 20】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值,必须实现Comparable是可比较的
     * @param <V>     操作值的类型
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> gt(Func1<T, V> getFunc, V value) {
        if (comeIntoForce(value)) {
            this.gt(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 in(值)】<br/>
     * 使用示例【.in(query::getId)】<br/>
     * 效果【id in(1,2,3)】<br/>
     *
     * @param getFunc 字段与值的lambda函数，函数的返回值必须实现Collection是一个集合
     * @return this
     */
    public <V extends Collection<?>> MyWrapper<T> in(Func0<V> getFunc) {
        V value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.in(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 in(值)】<br/>
     * 使用示例【.in(query::getId, userIds)】<br/>
     * 效果【id in(1,2,3)】<br/>
     *
     * @param getFunc 字段的lambda函数，
     * @param value   操作值,必须实现Collection是一个集合
     * @param <V>     操作值的类型
     * @param <E>     操作值的元素类型
     * @return this
     */
    public <E, V extends Collection<E>> MyWrapper<T> in(Func1<T, E> getFunc, V value) {
        if (comeIntoForce(value)) {
            this.in(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 not in(值)】<br/>
     * 使用示例【.notIn(query::getId)】<br/>
     * 效果【id in(1,2,3)】<br/>
     *
     * @param getFunc 字段与值的lambda函数，函数的返回值必须实现Collection是一个集合
     * @param <V>     操作值的类型
     * @return this
     */
    public <V extends Collection<?>> MyWrapper<T> notIn(Func0<V> getFunc) {
        V value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.notIn(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 小于等于判定【字段 in(值)】<br/>
     * 使用示例【.notIn(query::getId, userIds)】<br/>
     * 效果【id not in(1,2,3)】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值,必须实现Collection是一个集合
     * @param <V>     操作值的类型
     * @param <E>     操作值的元素类型
     * @return this
     */
    public <E, V extends Collection<E>> MyWrapper<T> notIn(Func1<T, E> getFunc, V value) {
        if (comeIntoForce(value)) {
            this.notIn(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 区间判定，不包含左右【字段 between startValue and endValue】<br/>
     * 使用示例【.between(query::getAge, 1, 20)】<br/>
     * 效果【age between 1 and 20】<br/>
     *
     * @param getFunc    字段的lambda函数
     * @param startValue 起始值
     * @param endValue   结束值
     * @param <V>        操作值必须为Comparable实现类，是可比较的
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> between(Func1<T, V> getFunc, V startValue, V endValue) {
        this.between(getColumn(getFunc), startValue, endValue);
        return this;
    }

    /**
     * 左右闭区间判定【字段 >= startValue and 字段 <= endValue】<br/>
     * 使用示例【.closedInterval(query::getAge, 1, 20)】<br/>
     * 效果【age >= 1 and age <= 20】<br/>
     *
     * @param getFunc    字段的lambda函数
     * @param startValue 起始值
     * @param endValue   结束值
     * @param <V>        操作值必须为Comparable实现类，是可比较的
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> closedInterval(Func1<T, V> getFunc, V startValue, V endValue) {
        if (comeIntoForce(startValue)) {
            this.ge(getFunc, startValue);
        }
        if (comeIntoForce(endValue)) {
            this.le(getFunc, endValue);
        }
        return this;
    }

    /**
     * 左开右闭区间判定【字段 > startValue and 字段 <= endValue】<br/>
     * 使用示例【.openLeftAndCloseRight(query::getAge, 1, 20)】<br/>
     * 效果【age > 1 and age <= 20】<br/>
     *
     * @param getFunc    字段的lambda函数
     * @param startValue 起始值
     * @param endValue   结束值
     * @param <V>        操作值必须为Comparable实现类，是可比较的
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> openLeftAndCloseRight(Func1<T, V> getFunc, V startValue, V endValue) {
        if (comeIntoForce(startValue)) {
            this.gt(getFunc, startValue);
        }
        if (comeIntoForce(endValue)) {
            this.le(getFunc, endValue);
        }
        return this;
    }

    /**
     * 左闭右开区间判定【字段 >= startValue and 字段 < endValue】<br/>
     * 使用示例【.closeLeftAndOpenRight(query::getAge, 1, 20)】<br/>
     * 效果【age >= 1 and age < 20】<br/>
     *
     * @param getFunc    字段的lambda函数
     * @param startValue 起始值
     * @param endValue   结束值
     * @param <V>        操作值必须为Comparable实现类，是可比较的
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> closeLeftAndOpenRight(Func1<T, V> getFunc, V startValue, V endValue) {
        if (comeIntoForce(startValue)) {
            this.ge(getFunc, startValue);
        }
        if (comeIntoForce(endValue)) {
            this.lt(getFunc, endValue);
        }
        return this;
    }

    /**
     * 左闭右开区间判定【字段 >= startValue and 字段 < endValue】<br/>
     * 使用示例【.closeLeftAndOpenRight(query::getAge, 1, 20)】<br/>
     * 效果【age >= 1 and age < 20】<br/>
     *
     * @param getFunc    字段的lambda函数
     * @param startValue 起始值
     * @param endValue   结束值
     * @param <V>        操作值必须为Comparable实现类，是可比较的
     * @return this
     */
    public <V extends Comparable<? super V>> MyWrapper<T> openLeftAndOpenRight(Func1<T, V> getFunc, V startValue, V endValue) {
        if (comeIntoForce(startValue)) {
            this.gt(getFunc, startValue);
        }
        if (comeIntoForce(endValue)) {
            this.lt(getFunc, endValue);
        }
        return this;
    }

    /**
     * 等于判定【字段 = 值】<br/>
     * 使用示例【.eq(user::getId)】<br/>
     * 效果【id = 1】<br/>
     *
     * @param getFunc 字段与值的lambda函数
     * @param <V>     操作值类型约束
     * @return this
     */
    public <V> MyWrapper<T> eq(Func0<V> getFunc) {
        V value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.eq(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 等于判定【字段 = 值】<br/>
     * 使用示例【.eq(query::getId, 1)】<br/>
     * 效果【id = 1】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值
     * @param <V>     操作值类型约束
     * @return this
     */
    public <V> MyWrapper<T> eq(Func1<T, V> getFunc, V value) {
        if (comeIntoForce(value)) {
            this.eq(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 等于判定【字段 != 值】<br/>
     * 使用示例【.ne(user::getId)】<br/>
     * 效果【id != 1】<br/>
     *
     * @param getFunc 字段与值的lambda函数
     * @param <V>     操作值类型约束
     * @return this
     */
    public <V> MyWrapper<T> ne(Func0<V> getFunc) {
        V value = getFunc.callWithRuntimeException();
        if (comeIntoForce(value)) {
            this.ne(getColumn(getFunc), value);
        }
        return this;
    }

    /**
     * 等于判定【字段 != 值】<br/>
     * 使用示例【.ne(query::getId, 1)】<br/>
     * 效果【id != 1】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @param value   操作值
     * @param <V>     操作值类型约束
     * @return this
     */
    public <V> MyWrapper<T> ne(Func1<T, V> getFunc, V value) {
        if (comeIntoForce(value)) {
            this.ne(getColumn(getFunc), value);
        }
        return this;
    }


    /**
     * 顺序排序操作【order by 字段 desc】<br/>
     * 使用示例【.orderByDesc(UserEntity::getAge))】<br/>
     * 效果【order by age desc】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @return this
     */
    public MyWrapper<T> orderByDesc(Func1<T, Comparable<?>> getFunc) {
        return this.order(Order.DESC(getFunc));
    }

    /**
     * 顺序排序操作【order by 字段 asc】<br/>
     * 使用示例【.orderByAsc(UserEntity::getAge)】<br/>
     * 效果【order by age asc】<br/>
     *
     * @param getFunc 字段的lambda函数
     * @return this
     */
    public MyWrapper<T> orderByAsc(Func1<T, Comparable<?>> getFunc) {
        return this.order(Order.ASC(getFunc));
    }

    /**
     * 多值排序操作【order by 字段1 排序类型,字段2 排序类型,...】<br/>
     * 使用示例【.order(Order.DESC(UserEntity::getCreatedTime), Order.ASC(UserEntity::getPhone))】<br/>
     * 效果【order by created_time desc,phone asc】<br/>
     *
     * @param orders 排序条件数组
     * @return this
     */
    @SafeVarargs
    public final MyWrapper<T> order(Order<T>... orders) {
        for (Order<T> order : orders) {
            if (Order.ASC.equals(order.getSort())) {
                this.orderByAsc(getColumn(order.getFieldFun()));
            } else if (Order.DESC.equals(order.getSort())) {
                this.orderByDesc(getColumn(order.getFieldFun()));
            }
        }
        return this;
    }

}
